package com.sunyard.manage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.page.PageMethod;
import com.sunyard.dal.bo.device.lock.LockAddBO;
import com.sunyard.dal.bo.device.lock.LockEditorBO;
import com.sunyard.dal.bo.device.lock.LockQueryBO;
import com.sunyard.dal.bo.PaginationBO;
import com.sunyard.dal.dto.LockQueryResDTO;
import com.sunyard.dal.entity.Lock;
import com.sunyard.dal.entity.LockCopy;
import com.sunyard.dal.entity.Operator;
import com.sunyard.dal.entity.Organization;
import com.sunyard.dal.mapper.LockCopyMapper;
import com.sunyard.dal.mapper.LockMapper;
import com.sunyard.dal.mapper.OperatorMapper;
import com.sunyard.dal.mapper.OrganizationMapper;
import com.sunyard.enums.IsDeletedEnum;
import com.sunyard.enums.LockStatusEnum;
import com.sunyard.enums.LockTypeEnum;
import com.sunyard.enums.AuditTypeEnum;
import com.sunyard.manage.listenster.ExcelLister;
import com.sunyard.manage.service.LockService;
import com.sunyard.utils.DateUtil;
import com.sunyard.utils.ExcelOutput;
import com.sunyard.utils.Response.BaseResult;
import com.sunyard.utils.Response.GetResult;
import com.sunyard.utils.TokenUtil;
import com.sunyard.utils.manage.DataGrid;
import com.sunyard.utils.manage.PageQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static java.util.stream.Collectors.toList;

@Slf4j
@Service
public class LockServiceImpl implements LockService {

    @Autowired
    private LockMapper lockMapper;

    @Autowired
    private LockCopyMapper lockCopyMapper;

    @Autowired
    private OrganizationMapper organizationMapper;

    @Autowired
    private OperatorMapper operatorMapper;

    @Override
    public BaseResult<DataGrid<LockQueryResDTO>> getLockByPage(PaginationBO<LockQueryBO> queryBO, HttpServletRequest request) {
        LockQueryBO lockQueryBO = queryBO.getParams();
        log.info("终端信息查询入参：{}", JSON.toJSONString(lockQueryBO));
        String orgId = TokenUtil.getOrgId(request.getHeader("token"));
        if (StringUtils.isBlank(lockQueryBO.getOrgId())) {
            lockQueryBO.setOrgId(orgId);
        }
        //设置分页信息
        PageMethod.startPage(queryBO.getPageNo(), queryBO.getPageSize());
        List<Lock> lockList = lockMapper.getLockByPage(lockQueryBO);
        List<LockQueryResDTO> resList = new ArrayList<>();
        for (Lock lock : lockList) {
            LockQueryResDTO resDTO = new LockQueryResDTO();
            BeanUtil.copyProperties(lock, resDTO);
            resDTO.setCreateTime(DateUtil.getDateStr(DateUtil.YYYYMMDD_HHMMSS, lock.getCreateTime()));
            Organization organization = organizationMapper.getOrganizationByOrgId(String.valueOf(lock.getOrgId()));
            resDTO.setOrgName(organization.getOrgName());
            Operator operator = operatorMapper.getOperatorByOpId(lock.getCreateUser());
            String createUser = ObjectUtil.isNotNull(operator) ? operator.getOpName() : lock.getCreateUser();
            resDTO.setCreateUser(createUser);
            resDTO.setAdminId(lock.getAdminId());
            resList.add(resDTO);
        }
        DataGrid dataGrid = PageQuery.getDataGrids(lockList, resList);
        return GetResult.getResult(dataGrid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult addLock(LockAddBO addBO, HttpServletRequest request) {
        log.info("添加锁信息的入参为{}", JSON.toJSONString(addBO));
        String opId = TokenUtil.getOpId(request.getHeader("token"));
        //判断终端名称是否已经存在
        Lock lock = lockMapper.getLockByKeyName(addBO.getLockName());
        if (ObjectUtil.isNotNull(lock)) {
            return GetResult.getResultFail("锁名称已存在");
        }
        Lock addLock = new Lock();
        BeanUtil.copyProperties(addBO, addLock);
        addLock.setLockType(Integer.valueOf(addBO.getLockType()));
        addLock.setCreateTime(new Date());
        addLock.setCreateUser(opId);
        addLock.setStatus("1");
        addLock.setLockStatus(LockStatusEnum.DISABLE.getCode());
        addLock.setIsDeleted(IsDeletedEnum.NOT_DELETED.getCode());
        if (LockTypeEnum.EMPLOYEE.getCode().equals(addBO.getLockType())) {
            if (StringUtils.isBlank(addBO.getEmployeeId())) {
                return GetResult.getResultFail("请选择柜员");
            }
            Operator operator = operatorMapper.getOperatorByEmployeeId(addBO.getEmployeeId());
            if (!(addBO.getOrgId().equals(operator.getOrgId()))) {
                return GetResult.getResultFail("柜员不是该机构的");
            }
            addLock.setAdminId(addBO.getEmployeeId());
        }
        lockMapper.insert(addLock);
        lockMapper.updateLockSn();
        Lock lockByKeyName = lockMapper.getLockByKeyName(addBO.getLockName());
        //添加审核信息
        LockCopy lockCopy = new LockCopy();
        BeanUtil.copyProperties(lockByKeyName, lockCopy);
        lockCopy.setId(null);
        lockCopy.setLockId(lockByKeyName.getId());
        lockCopy.setAdminId(addBO.getAdminId());
        if ("1".equals(addBO.getIsCheck())) {
            //如果是同步审核，则复核人为申请复核人
            lockCopy.setCheckAdminId(addBO.getAdminId());
        }
        lockCopy.setOperateType(AuditTypeEnum.ADD.getCode());
        lockCopy.setUseAdminId(addBO.getEmployeeId());
        lockCopyMapper.insert(lockCopy);
        return GetResult.getResultSuccess("添加成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<Lock> updateLock(LockEditorBO lockEditorBO, HttpServletRequest request) {
        log.info("锁具信息修改入参：{}", JSON.toJSONString(lockEditorBO));
        String opId = TokenUtil.getOpId(request.getHeader("token"));
        String orgId = TokenUtil.getOrgId(request.getHeader("token"));
        //只能编辑本机构锁具
        if (!(lockEditorBO.getOrgId().equals(orgId))) {
            return GetResult.getResultFail("只能选择本机构进行修改");
        }
        Lock lock = new Lock();
        lock.setLockName(lockEditorBO.getLockName());
        lock.setLockType(Integer.valueOf(lockEditorBO.getLockType()));
        lock.setOrgId(lockEditorBO.getOrgId());
        lock.setMissionType(lockEditorBO.getMissionType());
        lock.setRemark(lockEditorBO.getRemark());
        lock.setLockSn(lockEditorBO.getLockSn());
        lock.setId(lockEditorBO.getId());
        // 复核状态 0待复核 1已复核(0异步，1同步)
        if ("1".equals(lockEditorBO.getIsCheck())) {
            lockMapper.updateByPrimaryKeySelective(lock);
        } else {
            Lock lockInfo = new Lock();
            lockInfo.setId(lockEditorBO.getId());
            lockInfo.setIsCheck(lockEditorBO.getIsCheck());
            lockMapper.updateByPrimaryKeySelective(lockInfo);
        }
        LockCopy lockCopy = new LockCopy();
        Lock resultLock = lockMapper.selectByPrimaryKey(lockEditorBO.getId());
        BeanUtil.copyProperties(resultLock, lockCopy);
        lockCopy.setId(null);
        lockCopy.setLockId(resultLock.getId());
        lockCopy.setOperateType(AuditTypeEnum.UPDATE.getCode());
        lockCopy.setCreateUser(opId);
        lockCopy.setUseAdminId(lockEditorBO.getEmployeeId());
        lockCopyMapper.insert(lockCopy);
        GetResult.getResultSuccess("修改成功");
        return GetResult.getResult(resultLock);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult deleteLock(Lock lock, HttpServletRequest request) {
        log.info("锁具信息删除入参：{}", JSON.toJSONString(lock));
        String opId = TokenUtil.getOpId(request.getHeader("token"));
        String orgId = TokenUtil.getOrgId(request.getHeader("token"));
        //只能编辑本机构锁具
        if (!(orgId.equals(lock.getOrgId()))) {
            return GetResult.getResultFail("只能选择本机构进行删除");
        }
        lock.setIsDeleted(IsDeletedEnum.DELETED.getCode());
        //复核状态 0待复核 1已复核(0异步，1同步)
        if ("1".equals(lock.getIsCheck())) {
            lockMapper.updateById(lock);
        } else {
            Lock lockInfo = new Lock();
            lockInfo.setId(lock.getId());
            lockInfo.setIsCheck(lock.getIsCheck());
            lockMapper.updateByPrimaryKeySelective(lockInfo);
        }

        LockCopy lockCopy = new LockCopy();
        Lock resultLock = lockMapper.selectByPrimaryKey(lock.getId());
        BeanUtil.copyProperties(resultLock, lockCopy);
        lockCopy.setId(null);
        lockCopy.setLockId(resultLock.getId());
        lockCopy.setOperateType(AuditTypeEnum.DELETE.getCode());
        lockCopy.setCreateUser(opId);
        lockCopy.setUseAdminId(lock.getAdminId());
        lockCopyMapper.insert(lockCopy);
        return GetResult.getResultSuccess("删除成功");
    }


    @Override
    public BaseResult exportLock(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String opId = TokenUtil.getOpId(request.getHeader("token"));
        if (StringUtils.isEmpty(opId)) {
            return GetResult.getResultFail("请先登陆系统");
        }
        String orgId = TokenUtil.getOrgId(request.getHeader("token"));
        //根据机构id获取所有子机构
        //List<String> sonOrgList=organizationMapper.getAllSonOrgIds(orgId);
        List<String> sonOrgList = new ArrayList<>();
        sonOrgList.add(orgId);
        List<Lock> resultLock = lockMapper.getLockInfoByOrg(sonOrgList);

        String title = "锁信息导出";
        String[] headers = new String[]{"名称", "机构", "锁编号", "场景类型", "复核状态", "日志翻转", "创建时间", "备注", "锁类型"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        dataList = resultLock.stream().map(lock -> {
            Object[] obj = new Object[headers.length];
            obj[0] = lock.getLockName();
            String orgName = organizationMapper.getOrgName(lock.getOrgId());
            obj[1] = orgName;
            obj[2] = lock.getLockSn();
            obj[3] = lock.getMissionType();
            String isCheck = lock.getIsCheck();
            if ("1".equals(isCheck)) {
                isCheck = "待复核";
            } else if ("2".equals(isCheck)) {
                isCheck = "已复核";
            }
            obj[4] = isCheck;
            String reversion = lock.getReversion();
            if ("1".equals(reversion)) {
                reversion = "不翻转";
            } else if ("2".equals(reversion)) {
                reversion = "翻转";
            }
            obj[5] = reversion;
            obj[6] = DateUtil.getDateStr(DateUtil.YYYYMMDD_HHMMSS, lock.getCreateTime());
            obj[7] = lock.getRemark();
            //1主管锁 2柜员锁 3柜员通锁
            String lockType = String.valueOf(lock.getLockType());
            if ("1".equals(lockType)) {
                lockType = "主管锁";
            } else if ("2".equals(lockType)) {
                lockType = "柜员锁";
            } else if ("3".equals(lockType)) {
                lockType = "柜员通锁";
            }
            obj[8] = lockType;
            return obj;
        }).collect(toList());
        OutputStream out = null;
        // 防止中文乱码
        String headStr = "attachment; filename=\"" + new String(title.getBytes("gb2312"), "ISO8859-1") + "\"";
        response.setContentType("octets/stream");
        response.setContentType("APPLICATION/OCTET-STREAM");
        response.setHeader("Content-Disposition", headStr);
        out = response.getOutputStream();
        ExcelOutput ex = new ExcelOutput(title, headers, dataList);
        ex.export(out);
        return null;
    }

    @Override
    public BaseResult<List<Operator>> selectUserInfo(Lock lock, HttpServletRequest request) {
        String opId = TokenUtil.getOpId(request.getHeader("token"));
        if (StringUtils.isEmpty(opId)) {
            return GetResult.getResultFail("您未登录系统！");
        }
        List<Operator> operatorList = operatorMapper.getListOperatorByOrgId(lock.getOrgId());
       /* List<Operator> resultList=new LinkedList<>();
        for (Operator operator:operatorList){
            if (!StringUtils.isEmpty(operator.getCellerNo())){
                resultList.add(operator);
            }
        }*/
        return GetResult.getResult(operatorList);
    }

    @Override
    public BaseResult importInfo(MultipartFile file, LockService lockService) throws Exception {
        InputStream in = file.getInputStream();
        EasyExcel.read(in, Lock.class, new ExcelLister(lockService)).sheet().doRead();
        return GetResult.getResultSuccess("导入数据成功！");
    }

    @Override
    public void addLocksList(List<Lock> list) {
        if (!list.isEmpty()) {
            lockMapper.insertListLocks(list);
        }
    }

    @Override
    public BaseResult audit(Lock lock, HttpServletRequest request) {
        String opId = TokenUtil.getOpId(request.getHeader("token"));
        if (StringUtils.isEmpty(opId)) {
            return GetResult.getResultFail("您还未登陆系统");
        }
        Lock lockInfo = lockMapper.selectByPrimaryKey(lock.getId());
        if ("1".equals(lockInfo.getIsCheck())) {
            return GetResult.getResultFail("已进行审核，请不要重复操作");
        }
        LockCopy lockCopy = lockCopyMapper.selectByLockSn(lock.getLockSn());
        Lock lockAsynchronous = new Lock();
        BeanUtil.copyProperties(lockCopy, lockAsynchronous);
        lockAsynchronous.setId(lock.getId());
        lockAsynchronous.setAdminId(lock.getAdminId());

        lockMapper.updateByPrimaryKey(lockAsynchronous);

        LockCopy lockCopyInfo = new LockCopy();
        lockCopyInfo.setId(lockCopy.getId());
        lockCopyInfo.setIsCheck(lock.getIsCheck());
        lockCopyMapper.updateByPrimaryKeySelective(lockCopyInfo);
        return GetResult.getResultSuccess("审核成功");
    }
}
